package com.petecat.interchan.base.project.service.impl;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.jxpath.servlet.ServletRequestAndContext;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.mhuang.common.util.DataUtils;
import com.petecat.interchan.base.param.entity.BsProperties;
import com.petecat.interchan.base.param.service.IParamService;
import com.petecat.interchan.base.project.entity.BsProject;
import com.petecat.interchan.base.project.entity.BsProjectTokenRecord;
import com.petecat.interchan.base.project.entity.CpuTime;
import com.petecat.interchan.base.project.entity.EsServer;
import com.petecat.interchan.base.project.entity.EsServerHistory;
import com.petecat.interchan.base.project.entity.EsServerSoftWareDTO;
import com.petecat.interchan.base.project.entity.EsSoftPercent;
import com.petecat.interchan.base.project.entity.EsSofts;
import com.petecat.interchan.base.project.entity.HardWareDisk;
import com.petecat.interchan.base.project.entity.ServerDisk;
import com.petecat.interchan.base.project.entity.ServerInfoDTO;
import com.petecat.interchan.base.project.mapper.IProjectMapper;
import com.petecat.interchan.base.project.service.IProjectService;
import com.petecat.interchan.base.syscustom.entity.SysUserProject;
import com.petecat.interchan.base.syscustom.service.ICustomService;
import com.petecat.interchan.base.util.ExeclOutFile;
import com.petecat.interchan.core.exception.BusinessException;
import com.petecat.interchan.core.service.impl.BaseServiceImpl;
import com.petecat.interchan.es.EsDaoInter;
import com.petecat.interchan.protocol.Result;
import com.petecat.interchan.protocol.base.custom.vo.SysCustomVO;
import com.petecat.interchan.protocol.base.param.vo.BsPropertiesQryVO;
import com.petecat.interchan.protocol.base.project.dto.BsProjectAddDTO;
import com.petecat.interchan.protocol.base.project.dto.BsProjectQryDTO;
import com.petecat.interchan.protocol.base.project.dto.BsProjectUpdDTO;
import com.petecat.interchan.protocol.base.project.vo.BsProjectQryVO;
import com.petecat.interchan.protocol.base.project.vo.CompanySelectVO;
import com.petecat.interchan.protocol.base.project.vo.ProjectTreeVO;
import com.petecat.interchan.protocol.data.Page;
import com.petecat.interchan.protocol.data.PageVO;
import com.petecat.interchan.protocol.sso.sysuser.SysUserAddDTO;
import com.petecat.interchan.redis.IdWorker;
import com.petecat.interchan.redis.commands.IRedisExtCommands;

@Service
public class ProjectServiceImpl extends BaseServiceImpl<BsProject, String> implements IProjectService {

	@Autowired
	private IProjectMapper projectMapper;

	@Autowired
	private IParamService paramService;

	@Autowired
	private IRedisExtCommands redisExtCommands;

	@Autowired
	private EsDaoInter esDao;

	@Autowired
	private Environment environment;

	@Autowired
	private ICustomService customService;

	private static final String ONE = "1";

	private final static String SYUSER_REDIS_USERID_TO_USER_PREKEY = "syur_user_uid_";

	@Override
	public PageVO<BsProjectQryVO> queryProjectByPage(BsProjectQryDTO projectQryDTO) {
		SysUserAddDTO sysUserAddDTO = redisExtCommands.hget(SYUSER_REDIS_USERID_TO_USER_PREKEY,
				projectQryDTO.getUserId(), SysUserAddDTO.class);
		if (null == sysUserAddDTO) {
			throw new BusinessException(Result.SYS_RESULT_FAILD, environment.getProperty("user_not_exites"));
		}
		String user = "0".equals(sysUserAddDTO.getIsMaster()) ? sysUserAddDTO.getUserid() : null;
		projectQryDTO.setUserId(user);
		BsProject sysCompany = DataUtils.copyTo(projectQryDTO, BsProject.class);
		int count = this.projectMapper.count(sysCompany);
		PageVO<BsProjectQryVO> pageVo = new PageVO<>();
		if (count > 0) {
			Page<BsProject> page = new Page<>();
			page.setRows(projectQryDTO.getRows());
			page.setStart(projectQryDTO.getStart());
			page.setRecord(sysCompany);
			List<BsProject> companyList = this.projectMapper.page(page);
			pageVo.setResult(DataUtils.copyTo(companyList, BsProjectQryVO.class));
		}
		pageVo.setTotalSize(count);
		return pageVo;
	}

	/**
	 * 修改项目状态
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void updateProjectById(String projectId, String state) {
		this.projectMapper.updateCompanyStateById(projectId, state);
	}

	/**
	 * 通过项目ID查询项目名称
	 */
	@Override
	public String getNameByProjectId(String peojectId) {
		return this.projectMapper.getNameByProjectId(peojectId);
	}
	
	/**
	 * 删除项目
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void deleteProjectById(String projectId) {
		this.projectMapper.deleteProjectById(projectId);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void modifyProjectById(BsProjectUpdDTO bsProjectUpdDTO, String userId) {
		BsProject bsProject = DataUtils.copyTo(bsProjectUpdDTO, BsProject.class);
		bsProject.setOperaorUserId(userId);
		bsProject.setOperatorTime(new Date());
		this.projectMapper.update(bsProject);
	}
	
	/**
	 * 通过token查询项目名称
	 */
	@Override
	public String queryServerName(String token) {
		return this.projectMapper.getServerNameByToken(token);
	}
	
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void saveProject(BsProjectAddDTO bsProjectAddDTO, String userId) {
		BsProject bsProject = DataUtils.copyTo(bsProjectAddDTO, BsProject.class);
		bsProject.setCreateTime(new Date());
		bsProject.setOperatorTime(new Date());
		bsProject.setId(String.valueOf(new IdWorker().nextId()));
		bsProject.setToken(String.valueOf(new IdWorker().nextId()));
		bsProject.setOperaorUserId(userId);
		bsProject.setUserId(userId);
		bsProject.setStatus("1");
		this.projectMapper.save(bsProject);
		// 保存项目信息后添加一条默认的参数配置
		BsProperties bsProperties = DataUtils.copyTo(bsProject, BsProperties.class);
		bsProperties.setId(String.valueOf(new IdWorker().nextId()));
		bsProperties.setProjectId(bsProject.getId());
		bsProperties.setStatus("1");
		bsProperties.setName("默认配置");
		paramService.save(bsProperties);
	}

	/**
	 * 下拉查询项目
	 */
	@Override
	public List<CompanySelectVO> queryProjectSelect(String userId) {
		SysUserAddDTO sysUserAddDTO = redisExtCommands.hget(SYUSER_REDIS_USERID_TO_USER_PREKEY, userId,
				SysUserAddDTO.class);
		if (null == sysUserAddDTO) {
			throw new BusinessException(Result.SYS_RESULT_FAILD, environment.getProperty("user_not_exites"));
		}
		String user = "0".equals(sysUserAddDTO.getIsMaster()) ? sysUserAddDTO.getUserid() : null;
		List<CompanySelectVO> list = this.projectMapper.queryProjectSelect(user);
		if (!list.isEmpty()) {
			return list;
		}
		return null;
	}

	// 通过项目ID去查询token
	public String getProjectTokenById(String id) {
		return this.projectMapper.getProjectTokenById(id);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void updProjectTokenById(String projectId, String projectToken,String userId) {
		BsProject bsProject = new BsProject();
		bsProject.setOperaorUserId(userId);
		bsProject.setOperatorTime(new Date());
		bsProject.setId(projectId);
		String newToken = String.valueOf(new IdWorker().nextId());
		bsProject.setToken(newToken);
		this.projectMapper.update(bsProject);
		//添加项目Token历史表
		BsProjectTokenRecord record = new BsProjectTokenRecord();
		record.setCreateTime(new Date());
		record.setId(String.valueOf(new IdWorker().nextId()));
		record.setNewToken(newToken);
		record.setOldToken(projectToken);
		record.setOperaorTime(new Date());
		record.setOperaorUserId(userId);
		record.setUserId(userId);
		record.setStatus("1");
		this.projectMapper.saveToken(record);
	}

	/**
	 * 查询项目下拉树
	 */
	@Override
	public PageVO<ProjectTreeVO> queryProjectByTree(BsProjectQryDTO projectQryDTO, String userId) {
		SysUserAddDTO sysUserAddDTO = redisExtCommands.hget(SYUSER_REDIS_USERID_TO_USER_PREKEY, userId,
				SysUserAddDTO.class);
		if (null == sysUserAddDTO) {
			throw new BusinessException(Result.SYS_RESULT_FAILD, environment.getProperty("user_not_exites"));
		}
		String user = "0".equals(sysUserAddDTO.getIsMaster()) ? sysUserAddDTO.getUserid() : null;
		projectQryDTO.setUserId(user);
		List<ProjectTreeVO> treeVO = this.projectMapper.queryProjectByTree(projectQryDTO);
		PageVO<ProjectTreeVO> page = new PageVO<ProjectTreeVO>();
		if (!treeVO.isEmpty()) {
			page.setResult(treeVO);
		}
		return page;
	}

	/**
	 * 通过Token查询项目所在的服务器ES信息
	 */
	@Override
	public List<EsServer> queryServerInfo(String token) {
		List<EsServer> list = new ArrayList<>();
		TransportClient client = null;
		EsServer esServer = null;
		HardWareDisk disk = null;
		String sourceAsString = "";
		try {
			client = esDao.getClient();
			QueryBuilder queryBuilder = QueryBuilders.termQuery("token", token);
			SearchResponse response = client.prepareSearch("monitor-server-status-common").addSort("status", SortOrder.DESC)
					.setQuery(queryBuilder).execute().get();
			SearchHits hits = response.getHits();
			if (hits.totalHits > 0) {
				for (SearchHit hit : hits.getHits()) {
					sourceAsString = hit.getSourceAsString();
					esServer = JSON.parseObject(sourceAsString, EsServer.class);
					Long runTime = null;
					if(esServer.getStopTime() != null) {
						runTime = Long.parseLong(esServer.getStopTime()) - Long.parseLong(esServer.getSendTime());
					}else {
						runTime = new Date().getTime() - Long.parseLong(esServer.getSendTime());
					}
					String stampToDate = stampToDate(runTime.toString(),null);
					esServer.setRunTime(stampToDate);
					TermQueryBuilder tokenQuery = QueryBuilders.termQuery("header.token", token);
					MatchQueryBuilder macQuery = QueryBuilders.matchQuery("header.mac", esServer.getMac());
					BoolQueryBuilder must = QueryBuilders.boolQuery().must(tokenQuery).must(macQuery);
					SearchResponse serverRep = client.prepareSearch("monitor-server-info")
							.addSort("body.sendTime", SortOrder.DESC).setQuery(must).setSize(1).execute().get();
					SearchHits serverHits = serverRep.getHits();
					if (serverHits.totalHits > 0) {
						for (SearchHit hit1 : serverHits.getHits()) {
							sourceAsString = hit1.getSourceAsString();
							JSONObject bodyJson = JSON.parseObject(sourceAsString).getJSONObject("body");
							JSONObject cpuJson = bodyJson.getJSONObject("cpu");
							esServer.setCpuLogicalCount(cpuJson.getString("logicalCount"));
							esServer.setCpuTotalCount(cpuJson.getString("total"));
							esServer.setPlatform(bodyJson.getString("platform"));
							esServer.setSystem(bodyJson.getString("system"));
							JSONObject memoryJson = bodyJson.getJSONObject("virtual_memory");
							esServer.setMemTotal(memoryJson.getString("total"));
							JSONObject diskJson = bodyJson.getJSONObject("disks");
							List<HardWareDisk> diskList = new ArrayList<>();
							JSONObject diskObject = null;
							for(Map.Entry<String,Object> map : diskJson.entrySet()) {
							    diskObject = JSONObject.parseObject(map.getValue().toString());
								disk = new HardWareDisk();
								disk.setDevice(map.getKey());
								disk.setTotal(diskObject.getString("total"));
								disk.setFstype(diskObject.getString("fstype"));
								diskList.add(disk);
							}
							esServer.setDiskList(diskList);
							esServer.setDiskCount(diskList.size());
						}
					}
					list.add(esServer);
				}
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		} finally {
			if (client != null) {
				esDao.resume(client);
			}
		}
		return list;
	}

	/**
	 * 将时间戳转换为时间
	 * @param time
	 * @param format
	 * @return
	 */
	public String stampToDate(String time, String format) {
		String res;
		format = format == null ? "HH:mm:ss" : format;
		time = time + "000";
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
		long lt = new Long(time);
		Date date = new Date(lt);
		res = simpleDateFormat.format(date);
		return res;
	}

	/**
	 * 通过Token和Mac查询服务器使用率%圖表
	 */
	@SuppressWarnings("unused")
	@Override
	public List<EsSoftPercent> queryServerPercent(ServerInfoDTO serverInfoDTO, String userId) {
		List<EsSoftPercent> list = new ArrayList<>();
		TransportClient client = null;
		String sourceAsString = "";
		String format = null;
		boolean cpuFlag = false;
		boolean memFlag = false;
		boolean diskFlag = false;
		if (null != serverInfoDTO.getType()) {
			if (serverInfoDTO.getType().equals("D")) {
				format = "yyyy-MM-dd hh:mm:ss";
			}
		}
		// 通过项目ID获取自定义配置信息
		SysCustomVO customByProjectId = customService.getCustomByProjectId(serverInfoDTO.getProjectId(), userId);
		//通过用户ID和项目id查询正在启用的配置信息
		BsPropertiesQryVO paramByProjectIdAndUserId = paramService.getParamByProjectIdAndUserId(customByProjectId.getProjectId(),userId);
		//硬件上传间隔
		String interval = paramByProjectIdAndUserId.getHUpInterval().toString();
		// 如果配置中不存再说明默认全部展示
		if (customByProjectId == null){
			cpuFlag = true;
			memFlag = true;
			diskFlag = true;
		} else {
			if (customByProjectId.getShowCpu().equals(ONE)) {
				cpuFlag = true;
			}
			if (customByProjectId.getShowMem().equals(ONE)) {
				memFlag = true;
			}
			if (customByProjectId.getShowDisk().equals(ONE)) {
				diskFlag = true;
			}

		}

		try {
			client = esDao.getClient();
			// 默认一个小时
			TermQueryBuilder tokenQuery = QueryBuilders.termQuery("header.token", serverInfoDTO.getToken());
			MatchQueryBuilder macQuery = QueryBuilders.matchQuery("header.mac", serverInfoDTO.getServerMac());
			RangeQueryBuilder includeUpper = QueryBuilders.rangeQuery("body.sendTime").gte(serverInfoDTO.getTime()).lt(serverInfoDTO.getNewTime());
			BoolQueryBuilder must = QueryBuilders.boolQuery().must(tokenQuery).must(macQuery).must(includeUpper);
			SearchResponse response = client.prepareSearch("monitor-hardware").addSort("body.sendTime", SortOrder.ASC).setSize(10000).setQuery(must).execute().get();
			SearchHits hits = response.getHits();
			String sendTime = null;
			// 存储X,Y数据
			List<String> xshaftData = new ArrayList<>();
			List<String> cpuYshaftData = new ArrayList<>();
			List<String> emeYshaftData = new ArrayList<>();
			List<ServerDisk> disks = new ArrayList<ServerDisk>();
			Map<String,String> map = new HashMap<>();
			ServerDisk serverDisk = null;
			JSONObject diskObject = null;
			if (hits.totalHits > 0) {
				List<String> sizeList = new ArrayList<>();
				Set<String> nameSet = new HashSet<>();
				
				for (SearchHit hit : hits.getHits()) {
					sourceAsString = hit.getSourceAsString();
					JSONObject bodyJson = JSON.parseObject(sourceAsString).getJSONObject("body");
					sendTime = bodyJson.getString("sendTime");
					sendTime = stampToDate(sendTime, format);
					xshaftData.add(sendTime);
					if (cpuFlag) {
						JSONObject cpuJson = JSONObject.parseObject(bodyJson.getString("cpu").toString());
						cpuYshaftData.add(cpuJson.getString("percent"));
					}
					if (memFlag) {
						JSONObject memJson = JSONObject.parseObject(bodyJson.getString("virtual_memory").toString());
						emeYshaftData.add(memJson.getString("percent"));
					}
					
					JSONObject jsonObject = bodyJson.getJSONObject("disks");
					
					for(Map.Entry<String, Object> entry : jsonObject.entrySet()) {
						diskObject = JSONObject.parseObject(entry.getValue().toString());
						/*  disk使用量和空闲量
						String used = diskObject.getString("used");
						String free = diskObject.getString("free");*/
						String percent = diskObject.getString("percent");
						nameSet.add(entry.getKey());
						sizeList.add(entry.getKey()+percent);
					}
				}
				
				//查询list和C:D:E:
				Integer diskSize = nameSet.size();
				
				Iterator<String> iterator = nameSet.iterator();//取出元素
				while (iterator.hasNext()) {
					String dName = iterator.next().toString();
					List<String> list1 = findListContotis(sizeList,dName);
					serverDisk = new ServerDisk();
					serverDisk.setDiskName(dName);
					serverDisk.setDiskSize(list1);
					disks.add(serverDisk);
				}
				if (cpuFlag) {
					// CPU
					EsSoftPercent percentCpu = new EsSoftPercent();
					percentCpu.setTitle("CPU使用率");
					percentCpu.setIntervalTime(interval);
					percentCpu.setXshaftData(xshaftData);
					percentCpu.setYshaftData(cpuYshaftData);
					list.add(percentCpu);
				}
				if(memFlag) {
					// 内存
					EsSoftPercent percentMem = new EsSoftPercent();
					percentMem.setTitle("内存使用率");
					percentMem.setIntervalTime(interval);
					percentMem.setXshaftData(xshaftData);
					percentMem.setYshaftData(emeYshaftData);
					list.add(percentMem);
				}
				EsSoftPercent percentDdisk = null;
				if(diskFlag) {
					percentDdisk = new EsSoftPercent();
					percentDdisk.setXshaftData(xshaftData);
					percentDdisk.setServerDisk(disks);
					percentDdisk.setTitle("磁盘使用率");
					percentDdisk.setIntervalTime(interval);
					list.add(percentDdisk);
				}
				
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		} finally {
			if (client != null) {
				esDao.resume(client);
			}
		}
		return list;
	}

	
	/**
	 * 查询启用和用户自定义首页的项目信息
	 */
	@Override
	public List<CompanySelectVO> queryProjectByCustom(String userId) {
		// 返回数据
		List<CompanySelectVO> queryProjectSelect = new ArrayList<>();
		// 通过用户ID去查询用户项目表查看是否有数据
		List<SysUserProject> userProjectList = customService.findUserProjectByUserId(userId);
		if (null != userProjectList) {
			// 如果查出来的数据大于0,说明用户使用了自定义
			if (userProjectList.size() != 0) {
				List<String> list = new ArrayList<>();
				userProjectList.parallelStream().forEach(user -> list.add(user.getProjectId()));
				// 通过项目ID查询项目信息
				queryProjectSelect = this.projectMapper.findProjectByProjectIds(list);
			}
		} else {
			queryProjectSelect = this.queryProjectSelect(userId);
		}
		if(!queryProjectSelect.isEmpty()) {
			for(CompanySelectVO selectVo : queryProjectSelect) {
				JSONObject projectServerTotal = getProjectServerTotal(selectVo.getToken());
				selectVo.setServerTotal(projectServerTotal.getString("serverTotal"));
				selectVo.setUserServerCount(projectServerTotal.getString("userServerCount"));
			}
		}
		return queryProjectSelect;
	}

	/**
	 * 查询用户自定义项目
	 */
	@Override
	public List<CompanySelectVO> queryCustomByUserId(String userId) {
		// 返回数据
		List<CompanySelectVO> queryProjectSelect = new ArrayList<>();
		// 通过用户ID去查询用户项目表查看是否有数据
		List<SysUserProject> userProjectList = customService.findUserProjectByUserId(userId);
		if (null != userProjectList) {
			// 如果查出来的数据大于0,说明用户使用了自定义
			if (userProjectList.size() != 0) {
				List<String> list = new ArrayList<>();
				userProjectList.parallelStream().forEach(user -> list.add(user.getProjectId()));
				// 通过项目ID查询项目信息
				queryProjectSelect = this.projectMapper.findProjectByProjectIds(list);
			}
		}
		if(!queryProjectSelect.isEmpty()) {
			for(CompanySelectVO selectVo : queryProjectSelect) {
				JSONObject projectServerTotal = getProjectServerTotal(selectVo.getToken());
				selectVo.setServerTotal(projectServerTotal.getString("serverTotal"));
				selectVo.setUserServerCount(projectServerTotal.getString("userServerCount"));
			}
		}
		// 用户没有使用自定义首页,这里什么都不展示
		return queryProjectSelect;
	}

	/**
	 * 查询用户没有自定义的项目
	 */
	@Override
	public List<CompanySelectVO> queryNoCustom(String userId, String[] ids) {
		// 查询出所有的登陆人管理的项目信息，最后过滤掉传过来的ID
		// 通过项目ID查询项目信息
		List<CompanySelectVO> queryProjectSelect = this.queryProjectSelect(userId);
		if (!queryProjectSelect.isEmpty() && ids.length != 0) {
			Iterator<CompanySelectVO> iterator = queryProjectSelect.iterator();
			while (iterator.hasNext()) {
				CompanySelectVO next = iterator.next();
				for (int i = 0; i < ids.length; i++) {
					if (next.getId().equals(ids[i])) {
						iterator.remove();
					}
				}
			}
		}
		if(!queryProjectSelect.isEmpty()) {
			for(CompanySelectVO selectVo : queryProjectSelect) {
				JSONObject projectServerTotal = getProjectServerTotal(selectVo.getToken());
				selectVo.setServerTotal(projectServerTotal.getString("serverTotal"));
				selectVo.setUserServerCount(projectServerTotal.getString("userServerCount"));
			}
		}
		return queryProjectSelect;
	}
	
	
	public List<String> findListContotis(List<String> list,String type){
		List<String> retList = new ArrayList<>();
		for(String s : list) {
			if(s.contains(type)) {
				retList.add(s.substring(3));
			}
		}
		return retList;
	}
	
	JSONObject josnServer = null;
	/**
	 * 通过Token查询项目服务器的总数量和开机数量
	 */
	public JSONObject getProjectServerTotal(String token){
		TransportClient client = null;
		try {
			josnServer = new JSONObject();
			client = esDao.getClient();
			TermQueryBuilder tokenTermQuery = QueryBuilders.termQuery("token", token);
			TermQueryBuilder statusTermQuery = QueryBuilders.termQuery("status", "1");
			BoolQueryBuilder must = QueryBuilders.boolQuery().must(statusTermQuery).must(tokenTermQuery);
			//查询所有的
			SearchResponse actionGet = client.prepareSearch("monitor-server-status-common").setSize(100).setQuery(tokenTermQuery).execute().actionGet();
			SearchHits hits = actionGet.getHits();
			Integer serverTotal = hits.getHits().length;
			//查询在线的
			SearchResponse usedServer = client.prepareSearch("monitor-server-status-common").setSize(100).setQuery(must).execute().actionGet();
			SearchHits usedHhits = usedServer.getHits();
			Integer usedCount = usedHhits.getHits().length;
			josnServer.put("serverTotal", serverTotal.toString());
			josnServer.put("userServerCount", usedCount.toString());
		} finally {
			if (client != null) {
				esDao.resume(client);
			}
		}
		return josnServer;
	}
	
	/**
	 * 通过Mac查询服务器历史信息 
	 */
	@Override
	public PageVO<EsServerHistory> EsServerHistory(String serverMac,String userId,String start,String rows) {
		PageVO<EsServerHistory> vo = new PageVO<>();
		TransportClient client = null;
		String sourceString = "";
		EsServerHistory history = null;
 		Long runTime = null;
 		String time = "";
		List<EsServerHistory> serverInfoList = new ArrayList<>();
		int begin = Integer.parseInt(start);
		int count = Integer.parseInt(rows);
		begin = (begin-1)*count;
		try {
			client = esDao.getClient();
			MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("mac", serverMac);
			//查询所有的
			SearchResponse actionGet = client.prepareSearch("monitor-server-status")
											 .setQuery(matchQuery)
											 .setFrom(begin)
											 .setSize(count)
											 .execute()
											 .actionGet();
			SearchHits hits = actionGet.getHits();
			vo.setTotalSize(((Number)hits.getTotalHits()).intValue());
			if(hits.getHits().length > 0) {
				for (SearchHit searchHit : hits) {
					sourceString = searchHit.getSourceAsString();
					history = JSONObject.parseObject(sourceString,EsServerHistory.class);
					if(history.getStopTime() != null) {
						runTime = Long.parseLong(history.getStopTime()) - Long.parseLong(history.getSendTime());
					}else {
						runTime = (new Date().getTime())/1000 - Long.parseLong(history.getSendTime());
					}
					//转换分钟
					time = converTime(((Number)runTime).intValue());
					history.setRunTime(time);
					serverInfoList.add(history);
				}
			}
		} finally {
			if (client != null) {
				esDao.resume(client);
			}
		}
		vo.setResult(serverInfoList);
		return vo;
	}
	List<EsSofts> softsList = new ArrayList<>();
	/**
	 * 查询最近的ES服务器软件信息
	 */
	public PageVO<EsSofts> queryEsSoftwareInfo(EsServerSoftWareDTO serverSoftWareDTO) {
		PageVO<EsSofts> pageVo = new PageVO<EsSofts>();
		Integer start = serverSoftWareDTO.getStart();
		Integer length = softsList.size();
		Integer row = start + serverSoftWareDTO.getRows();
		//如果到了最后一页就取最后的数据
		if(row > length) {
			row = length;
		}
		if(softsList.size()>0){
			//Es分页 softsList
			List<EsSofts> returnSoftsList = softsList.subList(start, row);
			pageVo.setResult(returnSoftsList);
			pageVo.setTotalSize(softsList.size());
			return pageVo;
		}
		TransportClient client = esDao.getClient();
		TermQueryBuilder tokenQuery = QueryBuilders.termQuery("header.token", serverSoftWareDTO.getToken());
		MatchQueryBuilder macQuery = QueryBuilders.matchQuery("header.mac", serverSoftWareDTO.getServerMac());
		BoolQueryBuilder must = QueryBuilders.boolQuery().must(tokenQuery).must(macQuery);
		SearchResponse actionGet = client.prepareSearch("monitor-software")
														.addSort("body.sendTime", SortOrder.DESC)
														.setSize(1)
														.setQuery(must)
														.execute()
														.actionGet();
		SearchHits hits = actionGet.getHits();
		EsSofts soft = null;
		JSONObject next = null;
		if(softsList.size() == 0) {
			try {
				if(hits.totalHits > 0) {
					for (SearchHit searchHit : hits.getHits()) {
						String sourceAsString = searchHit.getSourceAsString();
						JSONObject jsonObject = JSON.parseObject(sourceAsString).getJSONObject("body");
						JSONArray jsonArray = jsonObject.getJSONArray("softs");
						Iterator<Object> iterator = jsonArray.iterator();
						while (iterator.hasNext()) {
							next =  (JSONObject)iterator.next();
							soft = new EsSofts();
							soft.setCreateTime(next.getString("create_time"));
							soft.setMemoryPercent(next.getString("memory_percent"));
							soft.setCpuTimes(JSONObject.parseObject(next.getJSONObject("cpu_times").toString(), CpuTime.class));
							soft.setName(next.getString("name"));
							soft.setNumThreads(next.getString("num_threads"));
							soft.setPid(next.getString("pid"));
							soft.setUserName(next.getString("username"));
							soft.setStatus(next.getString("status"));
							softsList.add(soft);
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}finally {
				if (client != null) {
					esDao.resume(client);
				}
			}
		}
		//Es分页 softsList
		List<EsSofts> returnSoftsList = softsList.subList(start, row);
		pageVo.setResult(returnSoftsList);
		pageVo.setTotalSize(softsList.size());
		return pageVo;
	}
	

	public String converTime(int seconds) {
		int temp=0;
		int temp1 = 0;
		StringBuffer sb=new StringBuffer();
		temp = seconds/86400;
		temp1 = seconds/3600;
		if(temp != 0) {
			sb.append((temp<10)?""+temp+"天":""+temp+":");
		}
		if(temp1 != 0){
			temp1 = temp1/24;
			sb.append((temp1<10)?"0"+temp1+":":""+temp1+":");
		}
		temp=seconds%3600/60;
		sb.append((temp<10)?"0"+temp+":":""+temp+":");
		temp=seconds%3600%60;
		sb.append((temp<10)?"0"+temp:""+temp);
		return sb.toString();
	}
	
	
	
	
	
	/**
	 * 查询所有的项目服务器ES信息并导出Execl
	 * @throws IOException 
	 */
	public ResponseEntity<byte[]> queryAllServerInfo(){
		List<EsServer> list = new ArrayList<>();
		TransportClient client = null;
		EsServer esServer = null;
		HardWareDisk disk = null;
		String statusText = "";
		JSONArray head = null;
		JSONArray body = null;
		Integer indexNumber = 0;
		  ByteArrayOutputStream outputStream = null;
		ResponseEntity<byte[]> returnFile = null;
		String sourceAsString = "";
		List<JSONArray> jsonList = new ArrayList<>();
		try {
			client = esDao.getClient();
			SearchResponse searchResponse = client.prepareSearch("monitor-server-status-common")
											.execute().get();
			SearchHits hits = searchResponse.getHits();
			if (hits.totalHits > 0) {
				//只需要一个head
				String [] sz = new String[] {"服务器名称","系统版本","服务器状态","总运行时长","内存大小","CPU总个数","CPU物理个数","磁盘总数量"};
				
				for (SearchHit hit : hits.getHits()) {
					body = new JSONArray();
					sourceAsString = hit.getSourceAsString();
					
					esServer = JSON.parseObject(sourceAsString, EsServer.class);
					Long runTime = null;
					if(esServer.getStopTime() != null) {
						runTime = Long.parseLong(esServer.getStopTime()) - Long.parseLong(esServer.getSendTime());
					}else { 
						runTime = new Date().getTime() - Long.parseLong(esServer.getSendTime());
					}
					String stampToDate = stampToDate(runTime.toString(),null);
					esServer.setRunTime(stampToDate);
					TermQueryBuilder tokenQuery = QueryBuilders.termQuery("header.token", esServer.getToken());
					MatchQueryBuilder macQuery = QueryBuilders.matchQuery("header.mac", esServer.getMac());
					BoolQueryBuilder must = QueryBuilders.boolQuery().must(tokenQuery).must(macQuery);
					SearchResponse serverRep = client.prepareSearch("monitor-server-info")
							.addSort("body.sendTime", SortOrder.DESC).setQuery(must).setSize(1).execute().get();
					SearchHits serverHits = serverRep.getHits();
					if (serverHits.totalHits > 0) {
						for (SearchHit hit1 : serverHits.getHits()) {
							sourceAsString = hit1.getSourceAsString();
							JSONObject bodyJson = JSON.parseObject(sourceAsString).getJSONObject("body");
							JSONObject cpuJson = bodyJson.getJSONObject("cpu");
							esServer.setCpuLogicalCount(cpuJson.getString("logicalCount"));
							esServer.setCpuTotalCount(cpuJson.getString("total"));
							esServer.setPlatform(bodyJson.getString("platform"));
							esServer.setSystem(bodyJson.getString("system"));
							JSONObject memoryJson = bodyJson.getJSONObject("virtual_memory");
							esServer.setMemTotal(memoryJson.getString("total"));
							JSONObject diskJson = bodyJson.getJSONObject("disks");
							List<HardWareDisk> diskList = new ArrayList<>();
							JSONObject diskObject = null;
							//写入excel
							body.add(esServer.getHostname());
							body.add(bodyJson.getString("platform"));
							if("1".equals(esServer.getStatus())) {
								statusText = "正在运行";
							}else {
								statusText = "已经停止";
							} 
							body.add(statusText);
							body.add(esServer.getRunTime());
							body.add(getPrintSize(Long.parseLong(memoryJson.getString("total"))));
							body.add(cpuJson.getString("total"));
							body.add(cpuJson.getString("logicalCount"));
							for(Map.Entry<String,Object> map : diskJson.entrySet()) {
							    diskObject = JSONObject.parseObject(map.getValue().toString());
								disk = new HardWareDisk();
								sz = insert(sz, sz.length-1, map.getKey()+"磁盘容量"); 
								sz = insert(sz, sz.length-1, map.getKey()+"磁盘类型"); 
								body.add(getPrintSize(Long.parseLong(diskObject.getString("total"))));
								body.add(diskObject.getString("fstype"));
								disk.setDevice(map.getKey());
								disk.setTotal(diskObject.getString("total"));
								disk.setFstype(diskObject.getString("fstype"));
								diskList.add(disk);
							}
							body.add(diskList.size());
							esServer.setDiskList(diskList);
							esServer.setDiskCount(diskList.size());
						}
					}
					list.add(esServer);
					jsonList.add(body);
					String queryServerName = this.queryServerName(esServer.getToken());
					//创建一个excel工作簿
			        HSSFWorkbook workbook = new HSSFWorkbook();
					//创建文件 
			        head = new JSONArray(Arrays.asList(sz));
					HSSFWorkbook book = ExeclOutFile.expExcel(workbook,head, jsonList, queryServerName,indexNumber);
					//创建一个字节数组输出流对象
			        outputStream=new ByteArrayOutputStream();
			        try {
						book.write(outputStream);
					} catch (IOException e) {
						e.printStackTrace();
					}  
					indexNumber++;
				}
				
				try {
					
		        HttpHeaders headers=new HttpHeaders();
		        String fileName=new String("服务器信息.xls".getBytes("UTF-8"),"iso-8859-1");
		        headers.setContentDispositionFormData("attachment", fileName);
		        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
			    returnFile=new ResponseEntity<byte[]>
			                            (outputStream.toByteArray(),headers,HttpStatus.CREATED);
			    outputStream.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				} 
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		} finally {
			if (client != null) {
				esDao.resume(client);
			}
		}
		
		return returnFile;
	}
	//B转KB,MB,GB
	public static String getPrintSize(long size) {
		//如果字节数少于1024，则直接以B为单位，否则先除于1024，后3位因太少无意义
		if (size < 1024) {
			return String.valueOf(size) + "B";
		} else {
			size = size / 1024;
		}
		//如果原字节数除于1024之后，少于1024，则可以直接以KB作为单位
		//因为还没有到达要使用另一个单位的时候
		//接下去以此类推
		if (size < 1024) {
			return String.valueOf(size) + "KB";
		} else {
			size = size / 1024;
		}
		if (size < 1024) {
			//因为如果以MB为单位的话，要保留最后1位小数，
			//因此，把此数乘以100之后再取余
			size = size * 100;
			return String.valueOf((size / 100)) + "."
					+ String.valueOf((size % 100)) + "MB";
		} else {
			//否则如果要以GB为单位的，先除于1024再作同样的处理
			size = size * 100 / 1024;
			return String.valueOf((size / 100)) + "."
					+ String.valueOf((size % 100)) + "GB";
		}
	}
	
	 public static String[] insert(String[] arr,int i,String l){
	        //新建数组,对原数组扩容  
		 String[] arr1 = new String[arr.length+1];  
	        //将原数组数据赋值给新数组  
	        for(int j = 0;j<arr.length;j++){  
	            arr1[j] = arr[j];  
	        }  
	        //将大于i的数据向后移动一位  
	        for(int j = arr1.length-2;j>i;j--){  
	            arr1[j+1] = arr1[j];  
	        }  
	        //赋值到i位置  
	        arr1[i+1] = l;  
	        return arr1;  
	    }  

}
